/**
* ============================================
* @author:syf20020816@outlook.com
* @since:20240321
* @version:0.4.1
* @type:interface
* @description:
* # Pagination
* A component designed for navigating through pages, providing options for customization and various interactions.
* ## Properties
* - in property <Themes> theme: Themes.Dark; Specifies the theme of the pagination component, with a default of dark mode.
* - in-out property <int> active: 0; The current active page.
* - in property <int> page-size: 10; The number of items per page.
* - in property <int> total: 50; The total number of items across all pages.
* - in property <image> pre-icon: UseIcons.icons.Left; The icon used for the "previous page" button.
* - in property <image> next-icon: UseIcons.icons.Right; The icon used for the "next page" button.
* - in property <length> size: 18px; The size of the pagination component.
* - in property <int> visible-range: 5; The number of visible page buttons in the pagination component.
* ## Functions
* - pure function get-color(hover: bool, index: int, self-color: brush) -> brush; Determines the color of page buttons based on the hover state and if it's the active page.
* - pure function to-left() -> bool; Determines if the "move to left" action should be available based on the current active page and the total number of pages.
* - pure function to-right() -> bool; Determines if the "move to right" action should be available based on the current active page and the total number of pages.
* ## Callbacks
* - callback pre(int, int); Triggered when the "previous page" button is clicked.
* - callback next(int, int); Triggered when the "next page" button is clicked.
* - callback clicked(int, int); Triggered when a specific page number is clicked.
* ============================================
*/


import { UseIcons, Themes, PaddingType, UseSurrealismFn, ColorLevel } from "../../use/index.slint";
import { SIcon } from "../icon/index.slint";
import { SCard } from "../card/index.slint";
import { SText } from "../text/index.slint";
import { ScrollView } from "std-widgets.slint";

component PaginationItem {
    in property <Themes> theme: Themes.Dark;
    in property <PaddingType> padding-type;
    in property <length> size;
    in property <brush> background;
    in property <string> text;
    height: item.height;
    width: item.width;
    item := SCard {
        theme: root.theme;
        padding-type: root.padding-type;
        card-height: root.size;
        card-width: root.size;
        background: root.background;
        inner-text-l := SText {
            theme: root.theme;
            font-size: root.size;
            text: root.text;
        }
    }
}

export component Pagination {
    in property <Themes> theme: Themes.Dark;
    in-out property <int> active: 0;
    in property <int> page-size: 10;
    in property <int> total: 50;
    in property <image> pre-icon: UseIcons.icons.Left;
    in property <image> next-icon: UseIcons.icons.Right;
    in property <length> size: 18px;
    in property <int> visible-range: 5;
    private property <PaddingType> padding-type: PaddingType.Tip;
    private property <int> page-number: ceil(total / page-size);
    private property <int> pre-active: root.active;
    pure function get-color(hover: bool,index: int,self-color: brush) -> brush {
        if (hover) {
            return UseSurrealismFn.deeper(root.theme, self-color);
        } else {
            return root.active == index ? UseSurrealismFn.deeper(root.theme, self-color) : self-color;
        }
    }
    pure function to-left() -> bool {
        return (root.active >= root.visible-range - 2) && (root.active < root.page-number - 2);
    }
    pure function to-right() -> bool {
        return (root.active >= root.visible-range - 1) && (root.active < root.page-number - 1);
    }
    callback pre(int, int);
    callback next(int, int);
    callback clicked(int, int);
    HorizontalLayout {
        spacing: root.size / 1.75;
        pre-btn := SCard {
            theme: root.theme;
            card-height: root.size;
            card-width: root.size;
            padding-type: root.padding-type;
            pre-inner-icon := SIcon {
                colorize: self.get-colorize();
                theme: root.theme;
                source: pre-icon;
                height: root.size;
                width: root.size;
                clicked => {
                    if root.active != 0 {
                        root.active -= 1;
                        // debug((root.active >= root.visible-range - 2), (root.active < root.page-number - (root.visible-range - 2)));
                        if root.to-left() {
                            pages-layout.scroll-x += pages-layout.item-width;
                        }
                        root.pre-active = root.active;
                    }
                    root.pre(root.active, root.page-size);
                }
            }
        }

        Rectangle {
            HorizontalLayout {
                if root.visible-range >= root.page-number: HorizontalLayout {
                    spacing: root.size / 1.75;
                    for item[index] in root.page-number: Rectangle {
                        width: UseSurrealismFn.count-width(root.size, UseSurrealismFn.get-padding(root.padding-type).padding-left);
                        SCard {
                            theme: root.theme;
                            padding-type: root.padding-type;
                            card-height: root.size;
                            card-width: root.size;
                            background: get-color(touch-area.has-hover, index, UseSurrealismFn.get-color(root.theme, ColorLevel.Normal));
                            touch-area := TouchArea {
                                mouse-cursor: pointer;
                                clicked => {
                                    root.active = index;
                                    root.clicked(index, root.page-size);
                                }
                                inner-text := SText {
                                    theme: root.theme;
                                    font-size: root.size;
                                    text: item + 1;
                                }
                            }
                        }
                    }
                }
            }

            pages-layout := HorizontalLayout {
                in-out property <length> scroll-x: 0;
                in-out property <length> item-width: UseSurrealismFn.count-width(root.size, UseSurrealismFn.get-padding(root.padding-type).padding-left) + root.size / 1.75;
                if root.visible-range < root.page-number: HorizontalLayout {
                    spacing: root.size / 1.75;
                    l-page-item := Rectangle {
                        height: touch-area-l.height;
                        width: touch-area-l.width;
                        touch-area-l := TouchArea {
                            mouse-cursor: pointer;
                            height: l-item.height;
                            width: l-item.width;
                            l-item := PaginationItem {
                                text: 1;
                                theme: root.theme;
                                padding-type: root.padding-type;
                                size: root.size;
                                background: get-color(touch-area-l.has-hover, 0, UseSurrealismFn.get-color(root.theme, ColorLevel.Normal));
                            }

                            clicked => {
                                root.active = 0;
                                root.clicked(0, root.page-size);
                                if pages-layout.scroll-x != 0 {
                                    pages-layout.scroll-x = 0;
                                }
                                root.pre-active = root.active;
                            }
                        }
                    }

                    if (root.active > root.visible-range - 2):l-icon-wrap := Rectangle {
                        width: UseSurrealismFn.count-width(root.size, UseSurrealismFn.get-padding(root.padding-type).padding-left);
                        SIcon {
                            source: UseIcons.icons.More;
                        }
                    }

                    Rectangle {
                        // background: red;
                        clip: true;
                        width: (root.visible-range - 2) * l-page-item.width + (root.visible-range - 3) * layout.spacing;
                        Flickable {
                            interactive: false;
                            width: parent.width;
                            height: parent.height;
                            viewport-height: parent.height;
                            viewport-width: layout.width;
                            viewport-x: pages-layout.scroll-x;
                            layout := HorizontalLayout {
                                spacing: root.size / 1.75;
                                width: root.page-number * l-page-item.width + (root.page-number - 1) * layout.spacing;
                                for item[i-index] in root.page-number - 2: i-page-item := Rectangle {
                                    private property <int> real-index: item + 1;
                                    height: touch-area-i.height;
                                    width: touch-area-i.width;
                                    touch-area-i := TouchArea {
                                        mouse-cursor: pointer;
                                        height: i-item.height;
                                        width: i-item.width;
                                        i-item := PaginationItem {
                                            text: real-index + 1;
                                            theme: root.theme;
                                            padding-type: root.padding-type;
                                            size: root.size;
                                            background: get-color(touch-area-i.has-hover, i-page-item.real-index, UseSurrealismFn.get-color(root.theme, ColorLevel.Normal));
                                        }

                                        clicked => {
                                            root.active = i-page-item.real-index;
                                            root.clicked( i-page-item.real-index, root.page-size);
                                            if pages-layout.scroll-x != 0 {
                                                if root.active < root.visible-range - 1 {
                                                    pages-layout.scroll-x = 0;
                                                } else if root.active >= root.page-number - 2 {
                                                    pages-layout.scroll-x = - ((root.page-number - root.visible-range) * pages-layout.item-width);
                                                } else {
                                                    if (root.pre-active == root.page-number - 1) {
                                                        root.pre-active -= 1;
                                                    }
                                                    pages-layout.scroll-x -= (root.active - root.pre-active) * pages-layout.item-width;
                                                }
                                            }
                                            root.pre-active = i-page-item.real-index;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if (root.active < root.page-number - 2):r-icon-wrap := Rectangle {
                        width: UseSurrealismFn.count-width(root.size, UseSurrealismFn.get-padding(root.padding-type).padding-left);
                        SIcon {
                            source: UseIcons.icons.More;
                        }
                    }

                    r-page-item := Rectangle {
                        height: touch-area-r.height;
                        width: touch-area-r.width;
                        touch-area-r := TouchArea {
                            mouse-cursor: pointer;
                            height: r-item.height;
                            width: r-item.width;
                            r-item := PaginationItem {
                                text: root.page-number;
                                theme: root.theme;
                                padding-type: root.padding-type;
                                size: root.size;
                                background: get-color(touch-area-r.has-hover, root.page-number - 1, UseSurrealismFn.get-color(root.theme, ColorLevel.Normal));
                            }

                            clicked => {
                                root.active = root.page-number - 1;
                                root.clicked(root.page-number - 1, root.page-size);
                                pages-layout.scroll-x = - ((root.page-number - root.visible-range) * pages-layout.item-width);
                                root.pre-active = root.active;
                            }
                        }
                    }
                }
            }
        }

        next-btn := SCard {
            theme: root.theme;
            card-height: root.size;
            card-width: root.size;
            padding-type: root.padding-type;
            next-inner-icon := SIcon {
                colorize: self.get-colorize();
                theme: root.theme;
                source: next-icon;
                height: root.size;
                width: root.size;
                clicked => {
                    if root.active != page-number - 1 {
                        root.active += 1;
                        // debug((root.active >= root.visible-range - 1) && (root.active < root.page-number - 1));
                        if root.to-right() {
                            pages-layout.scroll-x -= pages-layout.item-width;
                        }
                        root.pre-active = root.active;
                    }
                    root.next(root.active, root.page-size);
                }
            }
        }
    }
}
